#ifndef SERVER_H
#define SERVER_H

#include <QDateTime>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QHttpServer>
#include <QIcon>
#include <QObject>
#include <QProtobufSerializer>
#include <QString>
#include <QUuid>
#include <QWebSocketServer>

#include "base.qpb.h"
#include "file.qpb.h"
#include "friend.qpb.h"
#include "gateway.qpb.h"
#include "message_storage.qpb.h"
#include "message_transmit.qpb.h"
#include "notify.qpb.h"
#include "speech_recognition.qpb.h"
#include "user.qpb.h"

//////////////////////////////////////////////////////
/// 工具函数
//////////////////////////////////////////////////////
static inline QString getFileName(const QString &path)
{
    QFileInfo fileInfo(path);
    return fileInfo.fileName();
}

// 封装日志打印宏
#define TAG QString("[%1:%2]").arg(getFileName(__FILE__), QString::number(__LINE__))

// 使用qDebug打印时自动加上TAG
#define LOG() qDebug().noquote() << TAG

static inline QString formatTime(int64_t timestamp)
{
    // 把时间戳转换成QDateTime
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);
    // 把QDateTime对象转换成“格式时间”
    return dateTime.toString("MM-dd HH:mm:ss");
}

// 通过这个函数获得 秒级 的时间
static inline int64_t getTime() { return QDateTime::currentSecsSinceEpoch(); }

// 根据QByteArray，转换成QIcon
static inline QIcon makeIcon(const QByteArray &byteArray)
{
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);
    QIcon icon(pixmap);
    return icon;
}

// 从指定文件中读取所有的二进制内容，返回一个QByteArray
static inline QByteArray loadFileToByteArray(const QString &path)
{
    QFile file(path);
    bool ok = file.open(QFile::ReadOnly);
    if (!ok)
    {
        LOG() << "文件打开失败！";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

// 把QByteArray中的内容写入到某个指定的文件里
static inline void writeByteArrayToFile(const QString &path, const QByteArray &content)
{
    QFile file(path);
    bool ok = file.open(QFile::ReadOnly);
    if (!ok)
    {
        LOG() << "文件打开失败！";
        return;
    }
    file.write(content);
    file.flush();
    file.close();
}

//////////////////////////////////////////////////////////////////
/// 辅助函数
//////////////////////////////////////////////////////////////////
MicroIMS::UserInfo makeUserInfo(int index, const QByteArray &avatar);

MicroIMS::MessageInfo makeTextMessageInfo(int index, const QString &chatSessionId, const QByteArray &avatar);

MicroIMS::MessageInfo makeImageMessageInfo(int index, const QString &chatSessionId, const QByteArray &avatar);

MicroIMS::MessageInfo makeFileMessageInfo(int index, const QString &chatSessionId, const QByteArray &avatar);

MicroIMS::MessageInfo makeSpeechMessageInfo(int index, const QString &chatSessionId, const QByteArray &avatar);

//////////////////////////////////////////////////////////////////
/// HTTP 服务器
//////////////////////////////////////////////////////////////////
class HttpServer : public QObject
{
    Q_OBJECT
  public:
    static HttpServer *getInstance();

    bool init();

    QHttpServerResponse getUserInfo(const QHttpServerRequest &req);

    QHttpServerResponse getFriendList(const QHttpServerRequest &req);

    QHttpServerResponse getChatSessionList(const QHttpServerRequest &req);

    QHttpServerResponse getApplyList(const QHttpServerRequest &req);

    QHttpServerResponse getRecent(const QHttpServerRequest &req);

    QHttpServerResponse newMessage(const QHttpServerRequest &req);

    QHttpServerResponse setNickname(const QHttpServerRequest &req);

    QHttpServerResponse setDesc(const QHttpServerRequest &req);

    QHttpServerResponse getPhoneVerifyCode(const QHttpServerRequest &req);

    QHttpServerResponse setPhone(const QHttpServerRequest &req);

    QHttpServerResponse setAvatar(const QHttpServerRequest &req);

    QHttpServerResponse removeFriend(const QHttpServerRequest &req);

    QHttpServerResponse addFriendApply(const QHttpServerRequest &req);

  private:
    static HttpServer *instance;
    HttpServer() {}

    QHttpServer _httpServer;
    QProtobufSerializer _serializer;

  signals:
};

//////////////////////////////////////////////////////////////////
/// Websocket 服务器
//////////////////////////////////////////////////////////////////
class WebsocketServer : public QObject
{
    Q_OBJECT
  public:
    static WebsocketServer *getInstance();

    bool init();

  private:
    static WebsocketServer *instance;
    WebsocketServer() : _websocketServer("websocket server", QWebSocketServer::NonSecureMode) {}

    QWebSocketServer _websocketServer;
    QProtobufSerializer _serializer;

    int _messageIndex = 0;

  signals:
    void sendTextResp();
    void sendFriendRemove();
    void sendAddFriendApply();
};

#endif // SERVER_H
